
package blackberry.util.field;

import net.rim.device.api.system.Application;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;

public class DjTwinkleField {
	
	public static final int DEFAULT_VISIBLE_TIME = 250;
	public static final int DEFAULT_NON_VISIBLE_TIME = 250;
	public static final int DEFAULT_REPEAT_NUM = 4;
	
	private static Thread thread;
	
	private Field field;
	private Manager manager;
	private int visibleTime;
	private int nonVisibleTime;
	private int repeatNum;
	private DjTwinkleEndListener endListener;
	
	public DjTwinkleField(Field field, Manager manager, int visibleTime,
			int nonVisibleTime, int repeatNum, DjTwinkleEndListener endListener) {
		super();
		this.field = field;
		this.manager = manager;
		this.visibleTime = visibleTime;
		this.nonVisibleTime = nonVisibleTime;
		this.repeatNum = repeatNum;
		this.endListener = endListener;
	}
	
	public DjTwinkleField(Field field, Manager manager, int repeatNum, 
			 DjTwinkleEndListener endListener) {
		this(field, manager, DEFAULT_VISIBLE_TIME, DEFAULT_NON_VISIBLE_TIME, 
				repeatNum, endListener);
	}
	
	public DjTwinkleField(Field field, Manager manager, DjTwinkleEndListener endListener) {
		this(field, manager, DEFAULT_REPEAT_NUM, endListener);
	}
	
	public void twinkle(){
		twinkle(field, manager, visibleTime, nonVisibleTime, repeatNum, endListener);
	}

	//핵심 메소드
	public static void twinkle(final Field field, final Manager manager, 
			final int visibleTime, final int nonVisibleTime, 
			final int repeatNum, final DjTwinkleEndListener endListener){
		
		interrupt();

		thread = new Thread() {
			public void run() {
				try {
					
					for (int i = 0; i < repeatNum; i++) {
						addField(field, manager);
						sleep(visibleTime);
						
						delField(field, manager);
						sleep(nonVisibleTime);
					}
					addField(field, manager);
					
					if (notNullEndListener(endListener))
						endListener.completed(field, manager);
					
				} catch (InterruptedException e) {
					
					if (notNullEndListener(endListener))
					endListener.interrupted(field, manager);
					
				}
			}

			private boolean notNullEndListener(
					final DjTwinkleEndListener endListener) {
				return endListener != null;
			}

		};
		thread.start();
	}
	
	public static void twinkle(Field field, Manager manager,int repeatNum, 
			DjTwinkleEndListener endListener){
		twinkle(field, manager, DEFAULT_VISIBLE_TIME, DEFAULT_NON_VISIBLE_TIME, 
				repeatNum, endListener);
	}
	
	public static void twinkle(Field field, Manager manager, DjTwinkleEndListener endListener){
		twinkle(field, manager, DEFAULT_REPEAT_NUM, endListener);
	}
	
	public static synchronized void addField(Field field, Manager manager) {
		if (field == null || field.getIndex() != -1) 
			return;
		synchronized (Application.getEventLock()) {
			manager.add(field);
		}
	}

	public static synchronized void delField(Field field, Manager manager) {
		if (field == null || field.getIndex() == -1) 
			return;
		synchronized (Application.getEventLock()) {
			manager.delete(field);
		}
	}
	
	//interrupt 관련
	public static void interrupt(){
		if (thread == null || thread.isAlive() == false)
			return;
		thread.interrupt();
		return;
	}
	
	public static void join() throws InterruptedException {
		thread.join();
	}
	
	public static boolean isAlive() {
		return thread.isAlive();
	}
}